Gravity column

This PRST example is based on the "1ph/gravityColumn.m" example found in MRST.

MATLAB code

The code we are trying to convert to Python is the following:

%% My First Flow Solver: Gravity Column
% In this example, we introduce a simple pressure solver and use it to
% solve the single-phase pressure equation
%
% $$\nabla\cdot v = q, \qquad
%    v=\textbf{--}\frac{K}{\mu} \bigl[\nabla p+\rho g\nabla z\bigr],$$
%
% within the domain [0,1]x[0,1]x[0,30] using a Cartesian grid with
% homogeneous isotropic permeability of 100 mD. The fluid has density 1000
% kg/m^3 and viscosity 1 cP and the pressure is 100 bar at the top of the
% structure.
%
% The purpose of the example is to show the basic steps for setting up,
% solving, and visualizing a flow problem. More details on the grid
% structure, the structure used to hold the solutions, and so on, are given
% in the <simpleBC.html basic flow-solver tutorial>.
try
    require incomp
catch %#ok<CTCH>
    mrstModule add incomp
end

%% Define the model
% To set up a model, we need: a grid, rock properties (permeability), a
% fluid object with density and viscosity, and boundary conditions.
gravity reset on
G          = cartGrid([1, 1, 30], [1, 1, 30]);
G          = computeGeometry(G);
rock.perm  = repmat(0.1*darcy(), [G.cells.num, 1]);
fluid      = initSingleFluid('mu' ,    1*centi*poise, ...
                             'rho', 1014*kilogram/meter^3);
bc  = pside([], G, 'TOP', 100.*barsa());

%% Assemble and solve the linear system
% To solve the flow problem, we use the standard two-point
% flux-approximation method (TPFA), which for a Cartesian grid is the same
% as a classical seven-point finite-difference scheme for Poisson's
% equation. This is done in two steps: first we compute the
% transmissibilities and then we assemble and solve the corresponding
% discrete system.
T   = computeTrans(G, rock);
sol = incompTPFA(initResSol(G, 0.0), G, T, fluid, 'bc', bc);

%% Plot the face pressures
clf
plotFaces(G, 1:G.faces.num, convertTo(sol.facePressure, barsa()));
set(gca, 'ZDir', 'reverse'), title('Pressure [bar]')
view(3), colorbar
set(gca,'DataAspect',[1 1 10]);
%%
displayEndOfDemoMessage(mfilename)

The rest of the example will walk through this example line for line, displaying the PRST examples.

Setup

Start by importing PRST.


In [1]:
%load_ext line_profiler

In [2]:
# For Python 3 compatibility
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np

# Enable MayaVi to work non-blocking in notebook
#import matplotlib
#matplotlib.use('Qt4Agg')
#matplotlib.interactive(True)

import prst
import prst.incomp as incomp
import prst.gridprocessing as gridprocessing
import prst.utils as utils
import prst.params as params
import prst.solvers as solvers
import prst.plotting as plotting

from prst.utils.units import *

In [3]:
help(prst)


Help on package prst:

NAME
    prst - Python Reservoir Simulation Toolbox.

FILE
    m:\prst\prst\__init__.py

PACKAGE CONTENTS
    gridprocessing
    incomp (package)
    io
    params (package)
    plotting
    solvers
    utils (package)

DATA
    __all__ = ['gridprocessing', 'io', 'incomp', 'plotting', 'utils', 'par...


Import the "incomp" module

try
    require incomp
catch %#ok<CTCH>
    mrstModule add incomp
end
%% Define the model
% To set up a model, we need: a grid, rock properties (permeability), a
% fluid object with density and viscosity, and boundary conditions.
gravity reset on

In [4]:
# PRST uses a single module-level variable to set the gravity
prst.gravity_reset()
print("Gravity vector:", prst.gravity)


Gravity vector: [ 0.       0.       9.80665]

Build the grid, setup fluid

G = cartGrid([1, 1, 30], [1, 1, 30]); G = computeGeometry(G); rock.perm = repmat(0.1*darcy(), [G.cells.num, 1]); fluid = initSingleFluid('mu' , 1*centi*poise, ... 'rho', 1014*kilogram/meter^3);


In [5]:
G = gridprocessing.cartGrid([1, 1, 30], [1, 1, 30])
print(G)


<PRST grid
  gridType: ['tensorGrid', 'cartGrid']
  cells: ['facePos', 'num', 'indexMap', 'faces']
  cartDims: [ 1  1 30]
  gridDim: 3
  faces: ['neighbors', 'nodes', 'num', 'tag', 'nodePos']
  nodes: ['num', 'coords']
>

Computing the geometry modifies the original grid in place, no assignment is necessary. Note that specifying the module is necessary in PRST. This avoids polluting the global namespace, at the cost of more verbosity.


In [6]:
gridprocessing.computeGeometry(G)


INFO:prst:Computing normals, areas and centroids...
INFO:prst:Computing cell volumes and centroids
Out[6]:
<prst.gridprocessing.Grid at 0x1589da58>

In [7]:
rock = params.rock.Rock(G, perm=0.1*darcy, poro=1)

In [8]:
fluid = incomp.fluid.SingleFluid(viscosity=1*centi*poise, density=1014*kilogram/meter**3)
print(fluid)


{'mu': 0.001, 'rho': 1014.0}

Set up boundary conditions. Constant pressure at top face.


In [9]:
bc = params.wells_and_bc.BoundaryCondition()
bc.addPressureSide(G, "top", 100*bar)


Out[9]:
<prst.params.wells_and_bc.BoundaryCondition at 0x15708048>

In [10]:
print(bc)


{'sat': None, 'type': array([['pressure']], 
      dtype='|S8'), 'value': array([[ 10000000.]]), 'face': array([[120]])}

Assemble and solve the linear system

%% Assemble and solve the linear system
% To solve the flow problem, we use the standard two-point
% flux-approximation method (TPFA), which for a Cartesian grid is the same
% as a classical seven-point finite-difference scheme for Poisson's
% equation. This is done in two steps: first we compute the
% transmissibilities and then we assemble and solve the corresponding
% discrete system.
T   = computeTrans(G, rock);
sol = incompTPFA(initResSol(G, 0.0), G, T, fluid, 'bc', bc);

In [11]:
T = solvers.computeTrans(G, rock)
resSol = solvers.initResSol(G, p0=0.0)
sol = incomp.incompTPFA(resSol, G, T, fluid, bc=bc)


M:\miniconda2-win64\lib\site-packages\numpy_groupies\utils.py:298: RuntimeWarning: overflow encountered in long_scalars
  maxval = np.iinfo(a_dtype).max * n

In [12]:
sol


Out[12]:
{'facePressure': array([[ 10004971.97155   ],
        [ 10004971.97155   ],
        [ 10014915.91464999],
        [ 10014915.91464999],
        [ 10024859.85774999],
        [ 10024859.85774999],
        [ 10034803.80084999],
        [ 10034803.80084999],
        [ 10044747.74394998],
        [ 10044747.74394998],
        [ 10054691.68704998],
        [ 10054691.68704998],
        [ 10064635.63014997],
        [ 10064635.63014997],
        [ 10074579.57324997],
        [ 10074579.57324997],
        [ 10084523.51634996],
        [ 10084523.51634996],
        [ 10094467.45944996],
        [ 10094467.45944996],
        [ 10104411.40254995],
        [ 10104411.40254995],
        [ 10114355.34564995],
        [ 10114355.34564995],
        [ 10124299.28874994],
        [ 10124299.28874994],
        [ 10134243.23184994],
        [ 10134243.23184994],
        [ 10144187.17494993],
        [ 10144187.17494993],
        [ 10154131.11804993],
        [ 10154131.11804993],
        [ 10164075.06114993],
        [ 10164075.06114993],
        [ 10174019.00424993],
        [ 10174019.00424993],
        [ 10183962.94734993],
        [ 10183962.94734993],
        [ 10193906.89044992],
        [ 10193906.89044992],
        [ 10203850.83354992],
        [ 10203850.83354992],
        [ 10213794.77664992],
        [ 10213794.77664992],
        [ 10223738.71974991],
        [ 10223738.71974991],
        [ 10233682.66284991],
        [ 10233682.66284991],
        [ 10243626.6059499 ],
        [ 10243626.6059499 ],
        [ 10253570.5490499 ],
        [ 10253570.5490499 ],
        [ 10263514.4921499 ],
        [ 10263514.4921499 ],
        [ 10273458.4352499 ],
        [ 10273458.4352499 ],
        [ 10283402.3783499 ],
        [ 10283402.3783499 ],
        [ 10293346.3214499 ],
        [ 10293346.3214499 ],
        [ 10004971.97155   ],
        [ 10004971.97155   ],
        [ 10014915.91464999],
        [ 10014915.91464999],
        [ 10024859.85774999],
        [ 10024859.85774999],
        [ 10034803.80084999],
        [ 10034803.80084999],
        [ 10044747.74394998],
        [ 10044747.74394998],
        [ 10054691.68704998],
        [ 10054691.68704998],
        [ 10064635.63014997],
        [ 10064635.63014997],
        [ 10074579.57324997],
        [ 10074579.57324997],
        [ 10084523.51634996],
        [ 10084523.51634996],
        [ 10094467.45944996],
        [ 10094467.45944996],
        [ 10104411.40254995],
        [ 10104411.40254995],
        [ 10114355.34564995],
        [ 10114355.34564995],
        [ 10124299.28874994],
        [ 10124299.28874994],
        [ 10134243.23184994],
        [ 10134243.23184994],
        [ 10144187.17494993],
        [ 10144187.17494993],
        [ 10154131.11804993],
        [ 10154131.11804993],
        [ 10164075.06114993],
        [ 10164075.06114993],
        [ 10174019.00424993],
        [ 10174019.00424993],
        [ 10183962.94734993],
        [ 10183962.94734993],
        [ 10193906.89044992],
        [ 10193906.89044992],
        [ 10203850.83354992],
        [ 10203850.83354992],
        [ 10213794.77664992],
        [ 10213794.77664992],
        [ 10223738.71974991],
        [ 10223738.71974991],
        [ 10233682.66284991],
        [ 10233682.66284991],
        [ 10243626.6059499 ],
        [ 10243626.6059499 ],
        [ 10253570.5490499 ],
        [ 10253570.5490499 ],
        [ 10263514.4921499 ],
        [ 10263514.4921499 ],
        [ 10273458.4352499 ],
        [ 10273458.4352499 ],
        [ 10283402.3783499 ],
        [ 10283402.3783499 ],
        [ 10293346.3214499 ],
        [ 10293346.3214499 ],
        [ 10000000.        ],
        [ 10009943.94309999],
        [ 10019887.88619999],
        [ 10029831.82929999],
        [ 10039775.77239999],
        [ 10049719.71549998],
        [ 10059663.65859998],
        [ 10069607.60169997],
        [ 10079551.54479997],
        [ 10089495.48789996],
        [ 10099439.43099996],
        [ 10109383.37409995],
        [ 10119327.31719995],
        [ 10129271.26029994],
        [ 10139215.20339994],
        [ 10149159.14649993],
        [ 10159103.08959993],
        [ 10169047.03269993],
        [ 10178990.97579993],
        [ 10188934.91889993],
        [ 10198878.86199992],
        [ 10208822.80509992],
        [ 10218766.74819992],
        [ 10228710.69129991],
        [ 10238654.63439991],
        [ 10248598.5774999 ],
        [ 10258542.5205999 ],
        [ 10268486.4636999 ],
        [ 10278430.40679991],
        [ 10288374.3498999 ],
        [ 10298318.2929999 ]]), 'flux': array([[  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  3.67657567e-19],
        [ -3.67657567e-19],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  3.67657567e-19],
        [ -3.67657567e-19],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  0.00000000e+00],
        [ -0.00000000e+00],
        [  5.71054063e-19],
        [  3.87225279e-19],
        [  3.87225279e-19],
        [  2.03396496e-19],
        [  3.87225279e-19],
        [  5.71054063e-19],
        [  5.71054063e-19],
        [  3.87225279e-19],
        [  3.87225279e-19],
        [  3.87225279e-19],
        [  5.71054063e-19],
        [  5.71054063e-19],
        [  3.87225279e-19],
        [  5.71054063e-19],
        [  3.87225279e-19],
        [  2.03396496e-19],
        [  3.87225279e-19],
        [  1.95677123e-20],
        [  2.03396496e-19],
        [  2.03396496e-19],
        [  3.87225279e-19],
        [  3.87225279e-19],
        [  3.87225279e-19],
        [  3.87225279e-19],
        [  3.87225279e-19],
        [  2.03396496e-19],
        [  1.95677123e-20],
        [ -1.64261071e-19],
        [  2.03396496e-19],
        [  1.95677123e-20],
        [ -1.64261071e-19]]), 'pressure': array([[ 10004971.97155   ],
        [ 10014915.91464999],
        [ 10024859.85774999],
        [ 10034803.80084999],
        [ 10044747.74394998],
        [ 10054691.68704998],
        [ 10064635.63014997],
        [ 10074579.57324997],
        [ 10084523.51634996],
        [ 10094467.45944996],
        [ 10104411.40254995],
        [ 10114355.34564995],
        [ 10124299.28874994],
        [ 10134243.23184994],
        [ 10144187.17494993],
        [ 10154131.11804993],
        [ 10164075.06114993],
        [ 10174019.00424993],
        [ 10183962.94734993],
        [ 10193906.89044992],
        [ 10203850.83354992],
        [ 10213794.77664992],
        [ 10223738.71974991],
        [ 10233682.66284991],
        [ 10243626.6059499 ],
        [ 10253570.5490499 ],
        [ 10263514.4921499 ],
        [ 10273458.4352499 ],
        [ 10283402.3783499 ],
        [ 10293346.3214499 ]]), 's': array([[ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.],
        [ 0.]])}

getCellNoFaces

Plotting

%% Plot the face pressures
clf
plotFaces(G, 1:G.faces.num, convertTo(sol.facePressure, barsa()));
set(gca, 'ZDir', 'reverse'), title('Pressure [bar]')
view(3), colorbar
set(gca,'DataAspect',[1 1 10]);

In [13]:
import prst.plotting as plotting
from prst.utils.units import convert
from mayavi import mlab
plotting.plotGrid(G, cell_data=convert(sol.pressure, to=bar),
                  colorbar=True, mlab_show=False)
mlab.axes()
mlab.show()


WARNING:traits.has_traits:DEPRECATED: traits.has_traits.wrapped_class, 'the 'implements' class advisor has been deprecated. Use the 'provides' class decorator.
Out[13]:
<mayavi.modules.axes.Axes at 0x1bea1a40>